/// <reference path = "./ShaderComponent.ts" />

module lcc$render {

const {ccclass, property, menu } = cc._decorator;

enum MacroValueType {
	/**
	 * 布尔
	 */
	BOOL,

	/**
	 * 数值
	 */
	VALUE,
}

@ccclass("lcc$render.ShaderMacro")
@menu("i18n:lcc-render.menu_component/ShaderMacro")
export class ShaderMacro extends ShaderComponent {

	_tag:string = "macro";

	@property()
	_checkMacro:string = "";
	@property({
		tooltip : "检测宏"
	})
	get checkMacro(){
		return this._checkMacro;
	}
	set checkMacro(value:string){
		if(this._checkMacro != value){
			this._checkMacro = value;
			this.onRenderUpdateMaterial();
			this.node.emit("shader_update_attribute");
		}
	}
	
	@property()
	_macroName:string = "";
	@property({
		tooltip : "定义宏"
	})
	get macroName(){
		return this._macroName;
	}
	set macroName(value:string){
		if(this._macroName != value){
			this._macroName = value;
			this.onRenderUpdateMaterial();
			this.node.emit("shader_update_attribute");
		}
	}

	@property({
		type : cc.Enum(MacroValueType)
	})
	_valueType:MacroValueType = MacroValueType.BOOL;
	@property({
		type : cc.Enum(MacroValueType),
		tooltip : "值类型"
	})
	get valueType(){
		return this._valueType;
	}
	set valueType(value_:MacroValueType){
		if(this._valueType != value_){
			this._valueType = value_;
			this.onRenderUpdateMaterial();
			this.node.emit("shader_update_attribute");
		}
	}

	@property()
	_bool:boolean = false;
	@property({
		visible (){
			return this._valueType == MacroValueType.BOOL;
		},
		tooltip : "布尔宏值"
	})
	get bool(){
		return this._bool;
	}
	set bool(value:boolean){
		if(this._bool != value){
			this._bool = value;
			this.onRenderUpdateMaterial();
			this.node.emit("shader_update_attribute");
		}
	}

	@property()
	_value:number = 0;
	@property({
		visible (){
			return this._valueType == MacroValueType.VALUE;
		},
		tooltip : "数值宏值"
	})
	get value(){
		return this._value;
	}
	set value(value:number){
		if(this._value != value){
			this._value = value;
			this.onRenderUpdateMaterial();
			this.node.emit("shader_update_attribute");
		}
	}
	
    onLoad(){
        this.node.on("render_update_material", this.onRenderUpdateMaterial, this);
    }

    onDestroy(){
		this.node.targetOff(this);
    }
    
	onEnable(){
        this.onStateUpdate(true);
	}

	onDisable(){
        this.onStateUpdate(false);
    }

    private onStateUpdate(enable:boolean){
		this.node.emit("shader_update_tag");
		this.onRenderUpdateMaterial();
		this.node.emit("shader_update_attribute");
	}
	
    private onRenderUpdateMaterial (comp:RenderSystem = this.getComponent(RenderSystem)) {
		if(comp && this._macroName){
			// make sure material is belong to self.
			//@ts-ignore
			let material = comp._materials[0];
			if (material) {
				if (!this._checkMacro || material.getDefine(this._checkMacro)) {
					if(this.enabled && material.getDefine(this._macroName) !== undefined){
						if(this._valueType == MacroValueType.BOOL){
							material.define(this._macroName, this._bool);
						}else{
							material.define(this._macroName, this._value);
						}
						//Editor.log("onRenderUpdateMaterial", this._bool);
					}
					//Editor.log("onRenderUpdateMaterial", this.enabled);
				}
			}
		}
    }
}

}
